package com.homedo.odin.solution.service.bizservice.oms;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.homedo.core.common.base.dto.Meta;
import com.homedo.core.common.exception.BizException;
import com.homedo.core.common.util.BeanUtils;
import com.homedo.core.common.util.DateUtils;
import com.homedo.core.common.util.ParamCheckUtil;
import com.homedo.odin.solution.contract.oms.ImportReq;
import com.homedo.odin.solution.contract.oms.ListDetailsResp;
import com.homedo.odin.solution.contract.oms.ListDownloadsResp;
import com.homedo.odin.solution.contract.oms.SolProductListResp;
import com.homedo.odin.solution.contract.oms.UpdateListStatusReq;
import com.homedo.odin.solution.enumcode.SqlEnum;
import com.homedo.odin.solution.enumcode.basic.ErrorCodeEnum;
import com.homedo.odin.solution.model.dto.ListDetail;
import com.homedo.odin.solution.model.dto.ListDownloadsDetail;
import com.homedo.odin.solution.model.dto.SolProductListDetail;
import com.homedo.odin.solution.model.entity.SolProductDetail;
import com.homedo.odin.solution.model.entity.SolProductList;
import com.homedo.odin.solution.model.entity.SolProductUse;
import com.homedo.odin.solution.model.entity.Solution;
import com.homedo.odin.solution.model.entity.UserBasic;
import com.homedo.odin.solution.service.PoiServiceImpl;
import com.homedo.odin.solution.service.SolProductDetailServiceImpl;
import com.homedo.odin.solution.service.SolProductListServiceImpl;
import com.homedo.odin.solution.service.SolProductUseServiceImpl;
import com.homedo.odin.solution.service.SolutionServiceImpl;
import com.homedo.odin.solution.service.UserBasicServiceImpl;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author: zhaoxudong
 * @date: 2018/3/7 19:08
 * @Description: 清单配置业务处理
 */
@Service
public class SolProductListBizService {

    private static final Logger logger = LoggerFactory.getLogger(SolProductListBizService.class);
    @Autowired
    SolProductListServiceImpl solProductListService;
    @Autowired
    SolProductDetailServiceImpl solProductDetailService;
    @Autowired
    SolProductUseServiceImpl useService;
    @Autowired
    SolutionServiceImpl solutionService;
    @Autowired
    UserBasicServiceImpl userBasicService;
    @Autowired
    private PoiServiceImpl poiService;

    /**
     * 查找方案清单列表
     */
    public SolProductListResp findSolList(Integer pageNum, Integer pageSize, String solName, Integer status) {
        ParamCheckUtil.checkPageParam(pageNum, pageSize);
        if (status == null || status < 0 || status > 2) {
            throw new BizException(Meta.CODE_451.getCode(), "status不合规");
        }
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<SolProductListDetail> info = new PageInfo<>(solProductListService.findSolList(solName, status));
        SolProductListResp resp = BeanUtils.transfrom(SolProductListResp.class, info);
        return resp;
    }

    /**
     * 更新清单状态
     */
    public void updateListStatus(UpdateListStatusReq request) {
        Long userId = request.getUserId();
        Integer status = request.getStatus();
        Integer listId = request.getListId();
        String userName = request.getUserName();
        ParamCheckUtil.checkLongUserId(request.getUserId());
        ParamCheckUtil.checkListId(request.getListId());
        if (StringUtils.isBlank(request.getUserName())) {
            throw new BizException(Meta.CODE_451.getCode(), "用户名称不能为空");
        }
        if (request.getStatus() != 0 && request.getStatus() != 1) {
            throw new BizException(Meta.CODE_451.getCode(), "status不合规");
        }
        if (status == 1) {
            //如果是上架，将同方案的其他清单状态改为下架
            SolProductList solProductList = solProductListService.getProductListById(listId);
            if (solProductList == null) {
                throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "没有查到对应的清单，请检查参数！");
            }
            //更新数据库，让之前方案对应的清单下架
            updateListStatusBySolId(userId, solProductList.getSolutionId(), userName);
        }
        Integer count = solProductListService.updateListStatus(userId, status, listId, userName);
        if (count <= 0) {
            throw new BizException(SqlEnum.FAIL.getCode(), "状态更新失败！");
        }
    }

    /**
     * 根据清单id查找清单详情
     */
    public ListDetailsResp findListDetailsByListId(Integer listId, Integer pageNum, Integer pageSize) {
        ParamCheckUtil.checkListId(listId);
        ParamCheckUtil.checkPageParam(pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<SolProductDetail> info = new PageInfo<>(solProductDetailService.findListDetailsByListId(listId));
        List<ListDetail> list = BeanUtils.batchTransform(ListDetail.class, info.getList());
        ListDetailsResp resp = BeanUtils.transfrom(ListDetailsResp.class, info);
        resp.setList(list);
        return resp;
    }

    /**
     * 根据清单id查找下载明细
     */
    public ListDownloadsResp findListDownloadsByListId(Integer listId, Integer pageNum, Integer pageSize) {
        ParamCheckUtil.checkListId(listId);
        ParamCheckUtil.checkPageParam(pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<ListDownloadsDetail> list = new PageInfo<>(useService.findList(listId));
        ListDownloadsResp resp = BeanUtils.transfrom(ListDownloadsResp.class, list);
        return resp;
    }

    /**
     * 导入清单模板
     */
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public void importList(ImportReq request) {
        Long userId = request.getUserId();
        String userName = request.getUserName();
        String url = request.getUrl();
        ParamCheckUtil.checkLongUserId(userId);
        if (StringUtils.isBlank(userName)) {
            throw new BizException(Meta.CODE_451.getCode(), "用户名字不能为空");
        }
        if (StringUtils.isBlank(url)) {
            throw new BizException(Meta.CODE_451.getCode(), "url参数不能为空");
        }
        //下载、解析资源
        try {
            Workbook book = poiService.getSheets(url);
            //判断方案编号是否存在
            Sheet sheet = book.getSheetAt(0);
            Row row = sheet.getRow(0);
            row.getCell(1).setCellType(CellType.STRING);
            String solutionIdTemp = row.getCell(1).getStringCellValue();
            if (StringUtils.isBlank(solutionIdTemp)) {
                throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "方案不存在,导入失败");
            }
            Long solutionId = Long.valueOf(solutionIdTemp.trim());
            logger.info("方案编号为：{}", solutionId);
            Solution solution = solutionService.findBySolutionId(solutionId);
            if (solution == null) {
                throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "方案不存在,导入失败");
            }
            //保存sol_product_list并获取listID
            Integer listId = saveSolList(solutionId, userId, userName);
            //保存清单详情
            saveSolListDetails(listId, userId, sheet, userName);
        } catch (IOException e) {
            logger.error("资源下载解析失败", e);
            throw new BizException(Meta.CODE_500.getCode(), "资源下载解析失败");
        }

    }

    /**
     * 保存清单详情
     *
     * @param listId 清单id
     * @param userId 用户id
     */
    private void saveSolListDetails(Integer listId, Long userId, Sheet sheet, String userName) {
        //解析sheet并获取清单详情
        List<SolProductDetail> details = poiService.parseSheetGetSolList(listId, userId, sheet, userName);
        //保存清单详情
        solProductDetailService.insertBatch(details);
    }


    private Integer saveSolList(Long solutionId, Long userId, String userName) {
        //更新数据库，让之前方案对应的清单下架
        updateListStatusBySolId(userId, solutionId, userName);
        //保存新的清单
        SolProductList solProductList = new SolProductList();
        solProductList.setCreatedBy(userId);
        solProductList.setCreatedName(userName);
        solProductList.setModifiedBy(userId);
        solProductList.setModifiedName(userName);
        solProductList.setSolutionId(solutionId);
        solProductList.setStatus(1);
        solProductListService.insert(solProductList);
        return solProductList.getId();
    }

    /**
     * 更新数据库，让之前方案对应的清单下架
     */
    private void updateListStatusBySolId(Long userId, Long solutionId, String userName) {
        solProductListService.updateListStatusBySolId(userId, solutionId, 0, userName);
    }

    /**
     * 下载清单详情
     */
    public void downloadsDetails(Integer useId, HttpServletResponse response) {
        ParamCheckUtil.checkUserId(useId);
        //查找下载内容
        SolProductUse productUse = useService.findById(useId);
        if (productUse == null) {
            throw new BizException(SqlEnum.FAIL.getCode(), "没有清单详情数据");
        }
        List<JSONObject> details = JSONArray.parseArray(productUse.getContent(), JSONObject.class);
        //获取下载用户昵称
        UserBasic userBasic = userBasicService.selectByUserId(productUse.getCreatedBy());
        String userNickname =
                StringUtils.isBlank(userBasic.getNickName()) ? userBasic.getUserName() : userBasic.getNickName();
        //获取方案id
        SolProductList productList = solProductListService.findOneById(productUse.getListId());
        Long solutionId = productList.getSolutionId();
        //生成excel
        Workbook exportXlsx = exportXlsx(details, solutionId, userNickname, productUse.getCreatedTime());
        //导出excel
        poiService.exportXlsx("下载详情", exportXlsx, response);
    }

    /**
     * 拼装excel内容
     *
     * @param details 清单详情
     * @param solutionId 方案id
     * @param userNickname 下载用户昵称
     * @param createdTime 下载时间
     */
    private Workbook exportXlsx(List<JSONObject> details, Long solutionId, String userNickname, Date createdTime) {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("sheet1");
        //列宽自适应
        sheet.autoSizeColumn(1, true);
        //设置样式
        CellStyle cellStyle = getCellStyle(workbook);
        //设置表头
        setHead(solutionId, userNickname, createdTime, sheet, cellStyle);
        //设置标题
        Map<String, String> titleMap = new LinkedHashMap<>();
        titleMap.put("sysSort", "系统分类");
        titleMap.put("sysType", "二级分类");
        titleMap.put("productName", "产品名称");
        titleMap.put("model", "型号");
        titleMap.put("brand", "品牌");
        titleMap.put("skuId", "sku编号");
        titleMap.put("amount", "数量");
        titleMap.put("unit", "单位");
        titleMap.put("price", "参考价");
        setTitle(cellStyle, sheet, titleMap);
        //设置内容
        setContent(cellStyle, sheet, details, titleMap);
        return workbook;

    }

    /**
     * 设置内容
     */
    private void setContent(CellStyle cellStyle, Sheet sheet, List<JSONObject> details, Map<String, String> titleMap) {
        int index = 2;
        for (int i = 0; i < details.size(); i++) {
            Row contentRow = sheet.createRow(index++);
            Iterator<String> iterator = titleMap.keySet().iterator();
            int j = 0;
            while (iterator.hasNext()) {
                Cell cell = contentRow.createCell(j++);
                cell.setCellValue(details.get(i).getString(iterator.next()));
                cell.setCellStyle(cellStyle);
            }
        }
    }

    /**
     * 设置标题
     */
    private void setTitle(CellStyle cellStyle, Sheet sheet, Map<String, String> titleMap) {
        Row titleRow = sheet.createRow(1);
        Iterator<String> iterator = titleMap.keySet().iterator();
        int i = 0;
        while (iterator.hasNext()) {
            Cell cell = titleRow.createCell(i++);
            cell.setCellValue(titleMap.get(iterator.next()));
            cell.setCellStyle(cellStyle);
        }
    }

    private void setHead(Long solutionId, String userNickname, Date createdTime, Sheet sheet, CellStyle cellStyle) {
        //创建表头
        Row headRow = sheet.createRow(0);
        //方案id
        Cell solutionCell = headRow.createCell(0);
        solutionCell.setCellValue("方案ID");
        solutionCell.setCellStyle(cellStyle);
        Cell solutionCellValue = headRow.createCell(1);
        solutionCellValue.setCellValue(solutionId.toString());
        solutionCellValue.setCellStyle(cellStyle);
        Cell cell = headRow.createCell(2);
        cell.setCellStyle(cellStyle);
        //合并单元格
        CellRangeAddress cra = new CellRangeAddress(0, 0, 1, 2);
        sheet.addMergedRegion(cra);
        //下载用户
        Cell user = headRow.createCell(3);
        user.setCellValue("下载用户");
        user.setCellStyle(cellStyle);
        Cell userName = headRow.createCell(4);
        userName.setCellValue(userNickname);
        userName.setCellStyle(cellStyle);
        //下载时间
        Cell downTime = headRow.createCell(5);
        downTime.setCellValue("下载时间");
        downTime.setCellStyle(cellStyle);
        Cell downTimeCon = headRow.createCell(6);
        downTimeCon.setCellValue(DateUtils.formatDate(createdTime, "yyyy年MM月dd日"));
        downTimeCon.setCellStyle(cellStyle);
        Cell cell1 = headRow.createCell(7);
        cell1.setCellStyle(cellStyle);
        Cell cell2 = headRow.createCell(8);
        cell2.setCellStyle(cellStyle);
        //合并单元格
        CellRangeAddress timeCra = new CellRangeAddress(0, 0, 6, 8);
        sheet.addMergedRegion(timeCra);
    }

    private CellStyle getCellStyle(Workbook workbook) {
        //设置样式
        CellStyle cellStyle = workbook.createCellStyle();
        //下边框
        cellStyle.setBorderBottom(BorderStyle.THIN);
        //左边框
        cellStyle.setBorderLeft(BorderStyle.THIN);
        //上边框
        cellStyle.setBorderTop(BorderStyle.THIN);
        //右边框
        cellStyle.setBorderRight(BorderStyle.THIN);
        //居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        return cellStyle;
    }
}
